/*
 * Copyrignt (c) xuzeshui.com. All Rights Reserved.
 * Author: Zeshui Xu<i@xuzeshui.com>
 * Created Time: 2015-11-14 15:17:52
 * Last Modified: 2015-11-15 19:44:18
 * File Name: password/password.go
 * Description:
 */
package password

import (
	"passport/account"
	"passport/captcha"
	"passport/errorcode"
	"passport/user"

	log "github.com/cihub/seelog"
)

var (
	passwordService *PasswordService
)

/*
	重置密码请求
*/
type ResetPasswordReq struct {
	Mobile   string `json:"mobile"`
	Captcha  string `json:"captcha"`
	Password string `json:"password"`
}

/*
	修改登录密码请求
*/
type ChangePasswordReq struct {
	OldPassword string `json:"old_password"`
	NewPassword string `json:"new_password"`
}

/*
	PasswordService
*/
type PasswordService struct{}

/*
	重置密码
*/
func (p *PasswordService) ResetPassword(req *ResetPasswordReq) (uint, string) {
	if req == nil {
		return errorcode.EC_RESETPASS_REQUEST_IS_NULL, "req is NULL"
	}
	if req.Mobile == "" {
		return errorcode.EC_RESETPASS_REQUEST_MOBILE_EMPTY, "mobile is empty"
	}
	if req.Captcha == "" {
		return errorcode.EC_RESETPASS_REQUEST_CAPTCHA_EMPTY, "captcha is empty"
	}
	if req.Password == "" {
		return errorcode.EC_RESETPASS_REQUEST_PASSWORD_EMPTY, "password is empty"
	}

	var userid string
	if ai, err := account.GetAccountService().GetAllAccountInfo(account.ACCOUNT_TYPE_MOBILE, req.Mobile); err != nil {
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	} else if ai == nil {
		return errorcode.EC_RESETPASS_ACCOUNT_NOT_EXISTS, "mobile is not exists"
	} else {
		if ai.IsFreezed() {
			log.Warnf("MobileResetPassword mobile is freezed. mobile: %s", req.Mobile)
			return errorcode.EC_RESETPASS_ACCOUNT_FREEZE, "mobile is freezed"
		}
		if !ai.IsBinded() {
			return errorcode.EC_RESETPASS_ACCOUNT_NOT_EXISTS, "mobile is not exists"
		}
		userid = ai.Userid
	}
	if userid == "" {
		log.Errorf("MobileResetPassword get userid empty.mobile: %s", req.Mobile)
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	}
	validateCaptchaReq := &captcha.ValidateCaptchaReq{
		Mobile:  req.Mobile,
		Bid:     captcha.CAPTCHA_MOBILE_RESET_PASSWORD,
		Captcha: req.Captcha,
	}
	if code, msg := captcha.GetCaptchaService().ValidateCaptchaForMobile(validateCaptchaReq); code != errorcode.EC_GL_SUCCESS {
		log.Warnf("MobileResetPassword validate captcha failed for mobile: %s, captcha: %s", req.Mobile, req.Captcha)
		return code, msg
	}

	uinfochanger := user.NewUserInfoChanger(userid)
	uinfochanger.SetPassword(req.Password)
	if err := uinfochanger.Save(); err != nil {
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	}

	captcha.GetCaptchaService().DeleteCaptchaInfoItem(req.Mobile, captcha.CAPTCHA_MOBILE_RESET_PASSWORD)
	return errorcode.EC_GL_SUCCESS, errorcode.Msg(errorcode.EC_GL_SUCCESS)
}

/*
	修改登录密码
*/
func (p *PasswordService) ChangePassword(userid string, req *ChangePasswordReq) (uint, string) {
	if userid == "" || req == nil {
		return errorcode.EC_CHGPASS_REQUST_EMPTY, "invalid requst params"
	}
	if req.OldPassword == "" {
		return errorcode.EC_CHGPASS_OLD_PASSWD_EMPTY, "old password is empty"
	}
	if req.NewPassword == "" {
		return errorcode.EC_CHGPASS_NEW_PASSWD_EMPTY, "new password is empty"
	}

	var oldPasswd string
	if ui, err := user.GetUserService().GetAllUserInfo(userid); err != nil {
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	} else if ui == nil {
		log.Errorf("GetAllUserInfo empty for userid: %s", userid)
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	} else {
		oldPasswd = ui.Password
	}

	if oldPasswd != req.OldPassword {
		return errorcode.EC_CHGPASS_OLD_PASSWD_INCORRECT, "old password is incorrect"
	}

	uinfochanger := user.NewUserInfoChanger(userid)
	uinfochanger.SetPassword(req.NewPassword)
	if err := uinfochanger.Save(); err != nil {
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	}
	return errorcode.EC_GL_SUCCESS, errorcode.Msg(errorcode.EC_GL_SUCCESS)
}

/*
	PasswordService处理对象
*/
func GetPasswordService() *PasswordService {
	return passwordService
}

func init() {
	passwordService = &PasswordService{}
}
